package com.hjwei.dynamicproxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;

/**
 * JDK动态代理 通过这种方式，被代理的对象(RealSubject)可以在运行时动态改变， 需要控制的接口
 * (Subject接口)可以在运行时改变，控制的方式(DynamicSubject类)也可以动态改变，从而实 现了非常灵活的动态代理关系。
 * java.lang.reflect.Proxy,java.lang.reflect.InvocationHandler 和Method.
 *
 * 在Proxy类中的在Proxy类中的newProxyInstance（）
 * public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces,
 * InvocationHandler h) throws IllegalArgumentException 参数说明：
 * ClassLoader loader：类加载器 Class<?>[]
 * interfaces：得到全部的接口
 * InvocationHandler h：得到InvocationHandler接口的子类实例
 *
 * <p>Ps:类加载器 在Proxy类中的newProxyInstance（）方法中需要一个ClassLoader类的实例，ClassLoader实际上对应的是类加载器，
 * 在Java中主要有一下三种类加载器;
 * Booststrap ClassLoader：此加载器采用C++编写，一般开发中是看不到的；
 * Extendsion ClassLoader：用来进行扩展类的加载，一般对应的是jre\lib\ext目录中的类;
 * AppClassLoader：(默认)加载classpath指定的类，是最常使用的是一种加载器。
 */
public class Test {

      public static void main(String[] args) {
        RealSubject rs = new RealSubject();
        InvocationHandler  ds = new DynamicSubject(rs);
        Class cls = rs.getClass();

        Subject subject= (Subject) Proxy.newProxyInstance(cls.getClassLoader(), cls.getInterfaces(), ds);
        subject.request();
      }

      /**
       * 对于JDK 的Proxy,有以下几点：
       * 1）Interface：对于JDK proxy，业务类是需要一个Interface的，这也是一个缺陷
       *
       * 2）Proxy，Proxy 类是动态产生的，这个类在调用Proxy.newProxyInstance(targetCls.getClassLoader,
       * targetCls.getInterface,InvocationHander)之后，会产生一个Proxy类的实例。实际上这个Proxy类也是存在的，不仅仅是类的实例。
       * 这个Proxy类可以保存到硬盘上。
       *
       * 3） Method:对于业务委托类的每个方法，现在Proxy类里面都不用静态显示出来
       *
       * 4） InvocationHandler: 这个类在业务委托类执行时，会先调用invoke方法。invoke方法再执行相应的代理操作，可以实现对业务方法的再包装
       */
}
